﻿<!--
// (c) Copyright Microsoft Corporation.
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.
-->

<UserControl x:Class="System.Windows.Controls.Samples.SegmentedSample"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:System.Windows.Controls.Samples"
    xmlns:datavis="clr-namespace:System.Windows.Controls.DataVisualization;assembly=System.Windows.Controls.DataVisualization.Toolkit">

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <StackPanel Grid.Row="0">
            <ContentControl Content="Segmented TreeMap" Style="{StaticResource Header}" />
            <TextBlock Style="{StaticResource Information}">
                This sample shows how to use an ItemDefinitionSelector to apply different color interpolators to different branches of the TreeMap.
            </TextBlock>
        </StackPanel>
        
        <datavis:TreeMap x:Name="treeMapControl" Grid.Row="1">
            <datavis:TreeMap.Interpolators>
                <datavis:SolidColorBrushInterpolator TargetName="Segment1Border" TargetProperty="Background" 
                                           DataRangeBinding="{Binding Value2}" From="White" To="DarkRed" />
                <datavis:SolidColorBrushInterpolator TargetName="Segment2Border" TargetProperty="Background" 
                                           DataRangeBinding="{Binding Value2}" From="White" To="DarkGreen" />
                <datavis:SolidColorBrushInterpolator TargetName="Segment3Border" TargetProperty="Background" 
                                           DataRangeBinding="{Binding Value2}" From="White" To="DarkBlue" />
            </datavis:TreeMap.Interpolators>

            <datavis:TreeMap.ItemDefinitionSelector>
                <local:SegmentItemDefinitionSelector>
                    
                    <datavis:TreeMapItemDefinition ItemsSource="{Binding Children}" ValueBinding="{Binding Value}" ChildItemPadding="1">
                        <DataTemplate>
                            <Border x:Name="NonLeafBorder" Background="Transparent" BorderBrush="Black" BorderThickness="1"/>
                        </DataTemplate>
                    </datavis:TreeMapItemDefinition>

                    <datavis:TreeMapItemDefinition ItemsSource="{Binding Children}" ValueBinding="{Binding Value}">
                        <DataTemplate>
                            <Border x:Name="Segment1Border" BorderBrush="Black" BorderThickness="1" ToolTipService.ToolTip="{Binding ToolTip}">
                                <TextBlock Text="{Binding Name}" Foreground="Black" FontSize="14" Margin="2,2,0,0" TextWrapping="Wrap" TextAlignment="Center" VerticalAlignment="Center"/>
                            </Border>
                        </DataTemplate>
                    </datavis:TreeMapItemDefinition>

                    <datavis:TreeMapItemDefinition ItemsSource="{Binding Children}" ValueBinding="{Binding Value}">
                        <DataTemplate>
                            <Border x:Name="Segment2Border" BorderBrush="Black" BorderThickness="1" ToolTipService.ToolTip="{Binding ToolTip}">
                                <TextBlock Text="{Binding Name}" Foreground="Black" FontSize="14" Margin="2,2,0,0" TextWrapping="Wrap" TextAlignment="Center" VerticalAlignment="Center"/>
                            </Border>
                        </DataTemplate>
                    </datavis:TreeMapItemDefinition>

                    <datavis:TreeMapItemDefinition ItemsSource="{Binding Children}" ValueBinding="{Binding Value}">
                        <DataTemplate>
                            <Border x:Name="Segment3Border" BorderBrush="Black" BorderThickness="1" ToolTipService.ToolTip="{Binding ToolTip}">
                                <TextBlock Text="{Binding Name}" Foreground="Black" FontSize="14" Margin="2,2,0,0" TextWrapping="Wrap" TextAlignment="Center" VerticalAlignment="Center"/>
                            </Border>
                        </DataTemplate>
                    </datavis:TreeMapItemDefinition>

                </local:SegmentItemDefinitionSelector>
            </datavis:TreeMap.ItemDefinitionSelector>
        </datavis:TreeMap>

  <src:SourceViewer xmlns:src="clr-namespace:System.Windows.Controls.Samples;assembly=System.Windows.Controls.Samples.Common" xmlns:sys="clr-namespace:System;assembly=mscorlib">
  <src:SourceFile Path="SegmentedSample.xaml">
    <src:SourceFile.Source>
      <sys:String>&lt;!--
// (c) Copyright Microsoft Corporation.
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.
--&gt;

&lt;UserControl x:Class="System.Windows.Controls.Samples.SegmentedSample"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:System.Windows.Controls.Samples"
    xmlns:datavis="clr-namespace:System.Windows.Controls.DataVisualization;assembly=System.Windows.Controls.DataVisualization.Toolkit"&gt;

    &lt;Grid&gt;
        &lt;Grid.RowDefinitions&gt;
            &lt;RowDefinition Height="Auto"/&gt;
            &lt;RowDefinition Height="*"/&gt;
        &lt;/Grid.RowDefinitions&gt;
        &lt;StackPanel Grid.Row="0"&gt;
            &lt;ContentControl Content="Segmented TreeMap" Style="{StaticResource Header}" /&gt;
            &lt;TextBlock Style="{StaticResource Information}"&gt;
                This sample shows how to use an ItemDefinitionSelector to apply different color interpolators to different branches of the TreeMap.
            &lt;/TextBlock&gt;
        &lt;/StackPanel&gt;
        
        &lt;datavis:TreeMap x:Name="treeMapControl" Grid.Row="1"&gt;
            &lt;datavis:TreeMap.Interpolators&gt;
                &lt;datavis:SolidColorBrushInterpolator TargetName="Segment1Border" TargetProperty="Background" 
                                           DataRangeBinding="{Binding Value2}" From="White" To="DarkRed" /&gt;
                &lt;datavis:SolidColorBrushInterpolator TargetName="Segment2Border" TargetProperty="Background" 
                                           DataRangeBinding="{Binding Value2}" From="White" To="DarkGreen" /&gt;
                &lt;datavis:SolidColorBrushInterpolator TargetName="Segment3Border" TargetProperty="Background" 
                                           DataRangeBinding="{Binding Value2}" From="White" To="DarkBlue" /&gt;
            &lt;/datavis:TreeMap.Interpolators&gt;

            &lt;datavis:TreeMap.ItemDefinitionSelector&gt;
                &lt;local:SegmentItemDefinitionSelector&gt;
                    
                    &lt;datavis:TreeMapItemDefinition ItemsSource="{Binding Children}" ValueBinding="{Binding Value}" ChildItemPadding="1"&gt;
                        &lt;DataTemplate&gt;
                            &lt;Border x:Name="NonLeafBorder" Background="Transparent" BorderBrush="Black" BorderThickness="1"/&gt;
                        &lt;/DataTemplate&gt;
                    &lt;/datavis:TreeMapItemDefinition&gt;

                    &lt;datavis:TreeMapItemDefinition ItemsSource="{Binding Children}" ValueBinding="{Binding Value}"&gt;
                        &lt;DataTemplate&gt;
                            &lt;Border x:Name="Segment1Border" BorderBrush="Black" BorderThickness="1" ToolTipService.ToolTip="{Binding ToolTip}"&gt;
                                &lt;TextBlock Text="{Binding Name}" Foreground="Black" FontSize="14" Margin="2,2,0,0" TextWrapping="Wrap" TextAlignment="Center" VerticalAlignment="Center"/&gt;
                            &lt;/Border&gt;
                        &lt;/DataTemplate&gt;
                    &lt;/datavis:TreeMapItemDefinition&gt;

                    &lt;datavis:TreeMapItemDefinition ItemsSource="{Binding Children}" ValueBinding="{Binding Value}"&gt;
                        &lt;DataTemplate&gt;
                            &lt;Border x:Name="Segment2Border" BorderBrush="Black" BorderThickness="1" ToolTipService.ToolTip="{Binding ToolTip}"&gt;
                                &lt;TextBlock Text="{Binding Name}" Foreground="Black" FontSize="14" Margin="2,2,0,0" TextWrapping="Wrap" TextAlignment="Center" VerticalAlignment="Center"/&gt;
                            &lt;/Border&gt;
                        &lt;/DataTemplate&gt;
                    &lt;/datavis:TreeMapItemDefinition&gt;

                    &lt;datavis:TreeMapItemDefinition ItemsSource="{Binding Children}" ValueBinding="{Binding Value}"&gt;
                        &lt;DataTemplate&gt;
                            &lt;Border x:Name="Segment3Border" BorderBrush="Black" BorderThickness="1" ToolTipService.ToolTip="{Binding ToolTip}"&gt;
                                &lt;TextBlock Text="{Binding Name}" Foreground="Black" FontSize="14" Margin="2,2,0,0" TextWrapping="Wrap" TextAlignment="Center" VerticalAlignment="Center"/&gt;
                            &lt;/Border&gt;
                        &lt;/DataTemplate&gt;
                    &lt;/datavis:TreeMapItemDefinition&gt;

                &lt;/local:SegmentItemDefinitionSelector&gt;
            &lt;/datavis:TreeMap.ItemDefinitionSelector&gt;
        &lt;/datavis:TreeMap&gt;
    &lt;/Grid&gt;
&lt;/UserControl&gt;
</sys:String>
    </src:SourceFile.Source>
  </src:SourceFile>
  <src:SourceFile Path="SegmentedSample.xaml.cs">
    <src:SourceFile.Source>
      <sys:String>// (c) Copyright Microsoft Corporation.
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.

using System.ComponentModel;
using System.Collections.Generic;

namespace System.Windows.Controls.Samples
{
    /// &lt;summary&gt;
    /// Sample showing how to use different item definitions per branch of a tree.
    /// &lt;/summary&gt;
    [Sample("(6) Segmented TreeMap", DifficultyLevel.Advanced)]
    [Category("TreeMap")]
    public partial class SegmentedSample : UserControl
    {
        /// &lt;summary&gt;
        /// Initializes a new instance of the SegmentedSample class.
        /// &lt;/summary&gt;
        public SegmentedSample()
        {
            InitializeComponent();
            Loaded += new RoutedEventHandler(SegmentedSample_Loaded);
        }

        /// &lt;summary&gt;
        /// Generate a tree with a given segment ID.
        /// &lt;/summary&gt;
        /// &lt;param name="depth"&gt;The depth of the tree.&lt;/param&gt;
        /// &lt;param name="maxChildren"&gt;The maximum number of children nodes allowed.&lt;/param&gt;
        /// &lt;param name="maxValue"&gt; The maximum value allowed for the node's metrics.&lt;/param&gt;
        /// &lt;param name="segmentID"&gt;The ID to segment to which the leaves belong.&lt;/param&gt;
        /// &lt;param name="name"&gt;The name of the node (for making node names).&lt;/param&gt;
        /// &lt;param name="random"&gt;A random number generator for controlling tree generation.&lt;/param&gt;
        /// &lt;returns&gt;A SegmentNode representing the root of the tree.&lt;/returns&gt;
        private SegmentNode GenerateTree(int depth, int maxChildren, int maxValue, int segmentID, string name, Random random)
        {
            SegmentNode node = new SegmentNode();
            node.Name = name;

            if (depth &lt;= 0)
            {
                node.Value = random.Next(1, maxValue);
                node.Value2 = random.Next(1, maxValue);
                node.Segment = segmentID;
                node.Children = new SegmentNode[0];
            }
            else
            {
                int numChildren = random.Next(2, maxChildren);
                
                node.Children = new List&lt;SegmentNode&gt;();
                for (int i = 0; i &lt; numChildren; i++)
                {
                    node.Children.Add(GenerateTree(depth - 1, maxChildren, maxChildren, segmentID, name + "." + i, random));
                }
            }

            return node;
        }

        /// &lt;summary&gt;
        /// Loads the XML sample data and populates the TreeMap.
        /// &lt;/summary&gt;
        /// &lt;param name="sender"&gt;The object where the event handler is attached.&lt;/param&gt;
        /// &lt;param name="e"&gt;The event data.&lt;/param&gt;
        private void SegmentedSample_Loaded(object sender, RoutedEventArgs e)
        {
            // Sample browser-specific layout change.
            SampleHelpers.ChangeSampleAlignmentToStretch(this);

            // Construct the tree.
            Random r = new Random();
            treeMapControl.ItemsSource = new List&lt;SegmentNode&gt;()
            {
                GenerateTree(2, 9, 10, 1, "A", r),
                GenerateTree(2, 7, 15, 2, "B", r),
                GenerateTree(2, 5, 20, 3, "C", r),
            };
        }
    }
}

</sys:String>
    </src:SourceFile.Source>
  </src:SourceFile>
  <src:SourceFile Path="SegmentNode.cs">
    <src:SourceFile.Source>
      <sys:String>// (c) Copyright Microsoft Corporation.
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.

using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Text;

namespace System.Windows.Controls.Samples
{
    /// &lt;summary&gt;
    /// Represents a node within a tree with value, name and belonging to a particular data segment.
    /// &lt;/summary&gt;
    public class SegmentNode
    {
        /// &lt;summary&gt;
        /// Gets or sets a value representing the segment to which a node belongs.
        /// &lt;/summary&gt;
        public int Segment { get; set; }

        /// &lt;summary&gt;
        /// Gets or sets the primary value associated with the node.
        /// &lt;/summary&gt;
        public double Value { get; set; }
        
        /// &lt;summary&gt;
        /// Gets or sets the second value associated with the node.
        /// &lt;/summary&gt;
        public double Value2 { get; set; }

        /// &lt;summary&gt;
        /// Gets or sets the name associated with the node.
        /// &lt;/summary&gt;
        public string Name { get; set; }

        /// &lt;summary&gt;
        /// Gets or sets a value representing the children of this division, conference, or league. Empty for teams.
        /// &lt;/summary&gt;
        [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "Simplifies samples.")]
        public IList&lt;SegmentNode&gt; Children { get; set; }

        /// &lt;summary&gt;
        /// Gets the desired tooltip content.
        /// &lt;/summary&gt;
        public string ToolTip
        {
            get
            {
                StringBuilder outStr = new StringBuilder();
                outStr.Append("Name: ").Append(Name);
                outStr.Append("\nValue: ").Append(Value);
                outStr.Append("\nValue2: ").Append(Value2);
                outStr.Append("\nSegment: ").Append(Segment);
                return outStr.ToString();
            }
        }
    }
}
</sys:String>
    </src:SourceFile.Source>
  </src:SourceFile>
  <src:SourceFile Path="SegmentItemDefinitionSelector.cs">
    <src:SourceFile.Source>
      <sys:String>// (c) Copyright Microsoft Corporation.
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.

using System.Collections.ObjectModel;
using System.Windows.Controls.DataVisualization;
using System.Windows.Markup;

namespace System.Windows.Controls.Samples
{
    /// &lt;summary&gt;
    /// Dynamically chooses a TreeMapItemDefinitionSelector based on segment number in the node.
    /// &lt;/summary&gt;
    [ContentProperty("Children")]
    public class SegmentItemDefinitionSelector : TreeMapItemDefinitionSelector
    {
        /// &lt;summary&gt;
        /// Gets the list of templates that this selector will choose from.
        /// &lt;/summary&gt;
        public Collection&lt;TreeMapItemDefinition&gt; Children { get; private set; }

        /// &lt;summary&gt;
        /// Initializes a new instance of the &lt;see cref="SegmentItemDefinitionSelector"/&gt; class. 
        /// &lt;/summary&gt;
        public SegmentItemDefinitionSelector()
        {
            Children = new Collection&lt;TreeMapItemDefinition&gt;();
        }

        /// &lt;summary&gt;
        /// Returns an instance of a SegmentItemDefinitionSelector class used to specify properties for the 
        /// current item. 
        /// &lt;/summary&gt;
        /// &lt;param name="treeMap"&gt;Reference to the TreeMap class.&lt;/param&gt;
        /// &lt;param name="item"&gt;One of the nodes in the ItemsSource hierarchy.&lt;/param&gt;
        /// &lt;param name="level"&gt;The level of the node in the hierarchy.&lt;/param&gt;
        /// &lt;returns&gt;The TreeMapItemDefinition to be used for this node. If this method returns null 
        /// the TreeMap will use the value of its ItemDefinition property.&lt;/returns&gt;
        public override TreeMapItemDefinition SelectItemDefinition(TreeMap treeMap, object item, int level)
        {
            SegmentNode node = item as SegmentNode;

            if (Children.Count &gt; 0 &amp;&amp; node != null &amp;&amp; node.Segment &gt;= 0)
            {
                int child = node.Segment % Children.Count;
                return Children[child];
            }
            else
            {
                return null;
            }
        }
    }
}
</sys:String>
    </src:SourceFile.Source>
  </src:SourceFile>
</src:SourceViewer>
    </Grid>
</UserControl>
